package cn.miju.wechatpay.auth;

import com.wechat.pay.contrib.apache.httpclient.Credentials;
import com.wechat.pay.contrib.apache.httpclient.Validator;
import com.wechat.pay.contrib.apache.httpclient.auth.CertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.execchain.ClientExecChain;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;

/**
 * <pre>
 *
 * 文件名 :  CustomWechatPayHttpClientBuilder
 * 创建时间 : 2023年03月14日 16:49
 * 文件描述 : 无
 *
 * </pre>
 *
 * @author Huzb
 * @version 1.0.0
 */
public class CustomWechatPayHttpClientBuilder extends HttpClientBuilder {
    private static final String OS = System.getProperty("os.name") + "/" + System.getProperty("os.version");
    private static final String VERSION = System.getProperty("java.version");
    private Credentials credentials;
    private Validator validator;

    private CustomWechatPayHttpClientBuilder() {
        super();

        String userAgent = String.format(
                "WechatPay-Apache-HttpClient/%s (%s) Java/%s",
                getClass().getPackage().getImplementationVersion(),
                OS,
                VERSION == null ? "Unknown" : VERSION);
        setUserAgent(userAgent);
    }

    public static CustomWechatPayHttpClientBuilder create() {
        return new CustomWechatPayHttpClientBuilder();
    }

    public CustomWechatPayHttpClientBuilder withMerchant(String merchantId, String serialNo, PrivateKey privateKey) {
        this.credentials = new CustomWechatPay2Credentials(merchantId, new PrivateKeySigner(serialNo, privateKey));
        return this;
    }


    /**
     * 自定义部分 - 添加代理地址的凭证构造方法
     *
     * @param merchantId 商户ID
     * @param serialNo   证书序列号
     * @param privateKey 私钥
     * @param proxyUrl   代理地址
     * @return CustomWechatPayHttpClientBuilder
     */
    public CustomWechatPayHttpClientBuilder withMerchant(String merchantId, String serialNo,
                                                         PrivateKey privateKey,
                                                         String proxyUrl) {
        this.credentials = new CustomWechatPay2Credentials(merchantId, new PrivateKeySigner(serialNo, privateKey), proxyUrl);
        return this;
    }

    public CustomWechatPayHttpClientBuilder withCredentials(Credentials credentials) {
        this.credentials = credentials;
        return this;
    }

    public CustomWechatPayHttpClientBuilder withWechatPay(List<X509Certificate> certificates) {
        this.validator = new WechatPay2Validator(new CertificatesVerifier(certificates));
        return this;
    }

    public CustomWechatPayHttpClientBuilder withProxy(HttpHost proxy) {
        // todo: 这里的代理设置不知道能不能解决 通过ng代理地址访问支付接口验签失败的问题，后续测试，如果可以解决则自定义微信签名部分全部使用SDK中的，不再自定义实现
        if (proxy != null) {
            this.setProxy(proxy);
        }
        return this;
    }

    public CustomWechatPayHttpClientBuilder withValidator(Validator validator) {
        this.validator = validator;
        return this;
    }

    @Override
    public CloseableHttpClient build() {
        if (credentials == null) {
            throw new IllegalArgumentException("缺少身份认证信息");
        }
        if (validator == null) {
            throw new IllegalArgumentException("缺少签名验证信息");
        }
        return super.build();
    }

    @Override
    protected ClientExecChain decorateProtocolExec(final ClientExecChain requestExecutor) {
        return new CustomSignatureExec(this.credentials, this.validator, requestExecutor);
    }
}
